<?php

/**
 * Author: Jblew (www.jblew.pl)
 * Description:
 *    This class saves css and javascript to cache and returns combined javascript and css files to reduce requests.
 */
class Optimiser {

    private static $javascript = array();
    private static $javascriptFiles = array();
    private static $javascriptLibraries = array();
    private static $css = array();
    private static $cssFiles = array();
    private static $cacheConfigName = "optimiser_cache";

    public static function addJavascriptCode($code) {
        self::$javascript[] = array('type' => 'code_block', 'code' => $code);
    }

    public static function addJavascriptFile($filepath, $cache = true) {
        if (!in_array($filepath, self::$javascriptFiles)) {
            self::$javascriptFiles[] = $filepath;
            self::$javascript[] = array('type' => 'file', 'path' => $filepath, 'cache' => $cache);
        }
    }

    public static function addJavascriptLibrary($filepath) {
        if (!in_array($filepath, self::$javascriptFiles)) {
            self::$javascriptFiles[] = $filepath;
            self::$javascriptLibraries[] = $filepath;
        }
    }

    public static function getJavascriptAsCodeBlock() {
        $code = "";
        foreach (self::$javascriptLibraries as $path) {
            $code .= file_get_contents($path) . "\n";
        }
        foreach (self::$javascript as $arr) {
            if ($arr['type'] == 'code_block') {
                $code .= $arr['code'] . "\n";
            } else {
                $code .= file_get_contents($arr['path']) . "\n";
            }
        }

        return "<script type=\"text/javascript\">\n" . $code . "\n</script>";
    }

    private static function saveJavascriptAndGenerateToken() {
        $sum = "";
        $code = "/**\n"
                . "* Javascript code generated by Optimiser, created by Jblew (www.jblew.pl).\n"
                . "*/\n\n";
        foreach (self::$javascriptLibraries as $path) {
            $sum .= md5($path);
        }
        foreach (self::$javascript as $arr) {
            if ($arr['type'] == 'code_block') {
                $sum .= md5($arr['code']);
            } else {
                $sum .= md5($arr['path']);
            }
        }

        if (($wcode = Cache::read('optimiser-js-' . $sum, self::$cacheConfigName)) === false) {
            foreach (self::$javascriptLibraries as $path) {
                $code .= file_get_contents($path) . "\n";
            }
            foreach (self::$javascript as $arr) {
                if ($arr['type'] == 'code_block') {
                    $code .= $arr['code'] . "\n";
                } else {
                    if ($arr['cache']) {
                        $code .= file_get_contents($arr['path']) . "\n";
                    }
                }
            }

            Cache::write('optimiser-js-' . $sum, $code, self::$cacheConfigName);
        }
        return $sum;
    }

    public static function saveJavascriptAndReturnHeadLink($optimiserJsPath = "/optimiser/optimiser/js") {
        $out = "<script type=\"text/javascript\" src=\"" . $optimiserJsPath . "/" . self::saveJavascriptAndGenerateToken() . "\"></script>";

        $code = "";
        foreach (self::$javascript as $arr) {
            if ($arr['type'] == 'file' && !$arr['cache']) {
                $code .= file_get_contents($arr['path']) . "\n";
            }
        }

        if (!empty($code) && $code != "") {
            $out .= "<script type=\"text/javascript\">\n" . $code . "\n</script>";
        }
        return $out;
    }

    public static function addCssCode($code, $media = "all") {
        self::$css[] = array('type' => 'code_block', 'code' => $code, 'media' => $media);
    }

    public static function addCssFile($filepath, $media = "all", $cache = true) {
        if (!in_array($filepath, self::$cssFiles)) {
            self::$cssFiles[] = $filepath;
            self::$css[] = array('type' => 'file', 'path' => $filepath, 'cache' => $cache, 'media' => $media);
        }
    }

    public static function getCssAsCodeBlock() {
        $code = "";
        foreach (self::$css as $arr) {
            $code .= "\n@media ".$arr['media']." {\n";
            if ($arr['type'] == 'code_block') {
                $code .= $arr['code'] . "\n";
            } else {
                $code .= file_get_contents($arr['path']) . "\n";
            }
            $code .= "}\n";
        }

        return "<style type=\"text/css\">\n" . $code . "\n</style>";
    }

    private static function saveCssAndGenerateToken() {
        $sum = "";
        $code = "/**\n"
                . "* Css code generated by Optimiser, created by Jblew (www.jblew.pl).\n"
                . "*/\n\n";
        foreach (self::$css as $arr) {
            if ($arr['type'] == 'code_block') {
                $sum .= md5($arr['code']);
            } else {
                $sum .= md5($arr['path']);
            }
        }

        if (($wcode = Cache::read('optimiser-css-' . $sum, self::$cacheConfigName)) === false) {
            foreach (self::$css as $arr) {
                $code .= "\n@media ".$arr['media']." {\n";
                if ($arr['type'] == 'code_block') {
                    $code .= $arr['code'] . "\n";
                } else {
                    if ($arr['cache']) {
                    $code .= file_get_contents($arr['path']) . "\n";
                    }
                }
                $code .= "}\n";
            }

            Cache::write('optimiser-css-' . $sum, $code, self::$cacheConfigName);
        }
        return $sum;
    }

    public static function saveCssAndReturnHeadLink($optimiserCssPath = "/optimiser/optimiser/css") {
        $out = "<link rel=\"stylesheet\" href=\"" . $optimiserCssPath . "/" . self::saveCssAndGenerateToken() . "\" type=\"text/css\" />";
    
        $code = "";
        foreach (self::$javascript as $arr) {
            if ($arr['type'] == 'file' && !$arr['cache']) {
                $code .= file_get_contents($arr['path']) . "\n";
            }
        }

        if (!empty($code) && $code != "") {
            $out .= "<style type=\"text/css\">\n" . $code . "\n</style>";
        }
        return $out;
    }

}

?>